﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SIGEB.Modelo;
using SIGEB.Prototipo.control;
using SIGEB.Modelo.moduloPrestamos;
using SIGEB.Modelo.moduloPerfiles;
using SIGEB.Modelo.moduloUsuarios;
using SIGEB.Modelo.moduloGrupo;

namespace SIGEB.Prototipo.Control
{
    public class controlPrestamo
    {
        #region "constructores"

        public controlPrestamo(controlPrincipal cp)
        {
            this.cp = cp;
            this.datos = cp.datos;
        }

        #endregion

        #region "validacion"

        internal bool adquisicionValido(string adquisicion)
        {
            return Validacion.LongitudCadenaValida(adquisicion, true, 20);
        }

        internal bool idUsuarioValido(string idUsuario)
        {
            return Validacion.LongitudCadenaValida(idUsuario, true, 20);
        }

        internal bool multaDiariaValido(string multaDiaria)
        {
            return Validacion.NumeroValido(multaDiaria, true, true);
        }

        internal bool idDocumentoValido(string idDocumento)
        {
            return Validacion.LongitudCadenaValida(idDocumento, false, 20);
        }

        internal bool fechaDevolucionValido(DateTime fechaDevolucion)
        {
            return Validacion.mayor(fechaDevolucion, DateTime.Now, true);
        }

        internal bool devolucionValida(string devolucion)
        {
            if (!Validacion.validaFecha(devolucion))
            {
                return false;
            }
            if (!Validacion.mayor(DateTime.Parse(devolucion), DateTime.Today, true))
            {
                return false;
            }
            return true;
        }

        internal bool camposPrestamoValidos(String idUsuario, String adquisicion, DateTime fechaDevolucion, String multaDiaria, String idDocumento)
        {
            return adquisicionValido(adquisicion) && idUsuarioValido(idUsuario) && fechaDevolucionValido(fechaDevolucion) && multaDiariaValido(multaDiaria) && idDocumentoValido(idDocumento) && usuarioValido(idUsuario) && ejemplarValido(adquisicion);
        }

        internal bool idPrestamoValido(string idPrestamo)
        {
            return Validacion.LongitudCadenaValida(idPrestamo, true, 20);
        }

        internal bool usuarioValido(String idUsuario)
        {
            if (!cp.ctrlUsuario.existeUsuario(idUsuario))
                return false;
            else
                return true;
        }

        internal bool ejemplarValido(String idEjemplar)
        {
            if (!cp.ctrlEjemplares.existeEjemplar(idEjemplar))
                return false;
            else
                return true;
        }

        #endregion

        #region "metodos"

        internal void crearPrestamo(String idUsuario, String adquisicion, DateTime devolucion, String multaDiaria, String idDocumento)
        {
            DateTime fechaPrestamo = DateTime.Today;
            if (!camposPrestamoValidos(idUsuario,adquisicion,devolucion,multaDiaria, idDocumento))
            {
                throw new Exception("Error en los valores del préstamo");
            }
            if (!cp.usuarioActualPuede(acciones.PRESTA_REGISTRAR))
            {
                cp.ExcepcionUsrSinPermisos();
            }
            cp.datos.prestamos.agregarprestamo(new prestamo(null, adquisicion, fechaPrestamo, devolucion, double.Parse(multaDiaria), idUsuario));
        }

        internal void validarPrestamo(String idUsuario, String adquisicion, DateTime devolucion, String multaDiaria, String idDocumento)
        {
            DateTime fechaPrestamo = DateTime.Today;
            if (!camposPrestamoValidos(idUsuario, adquisicion, devolucion, multaDiaria, idDocumento))
            {
                throw new Exception("Error en los valores del préstamo");
            }
            if (!cp.usuarioActualPuede(acciones.PRESTA_REGISTRAR))
            {
                cp.ExcepcionUsrSinPermisos();
            }
        }

        internal void validaExistenciaPrestamo(String numAdqui)
        {
            prestamo nuevo = cp.datos.prestamos.obtenerPrestamoNumAdqui(numAdqui);
            if (nuevo != null)
                 throw new Exception("Ejemplar no disponible");
        }

        internal void eliminarPrestamoDoc(String adquisicion)
        {
            if (!adquisicionValido(adquisicion))
            {
                throw new Exception("Número de adquisición inválido");
            }
            if (!cp.usuarioActualPuede(acciones.PRESTA_ELIMINAR))
            {
                cp.ExcepcionUsrSinPermisos();
            }
            cp.datos.prestamos.eliminarprestamo(adquisicion);
        }

        internal void devolverEjemplar(String idEjemplar)
        {
            if (!idPrestamoValido(idEjemplar))
            {
                throw new Exception("El idEjemplar es inválido");
            }
            if (!cp.usuarioActualPuede(acciones.PRESTA_DEVOLVER))
            {
                cp.ExcepcionUsrSinPermisos();
            }
            cp.datos.prestamos.procesarDevolucion(idEjemplar);
        }

        internal LinkedList<prestamo> prestamoUsuarioEstado(String idUsuario, int estado)
        {
            if (!idUsuarioValido(idUsuario))
            {
                throw new Exception("El idUsuario es inválido");
            }
            if (!cp.usuarioActualPuede(acciones.PRESTA_CONSULTA_TOD))
            {
                if (cp.usuarioActualPuede(acciones.PRESTA_CONSULTA_ACT) && idUsuario == cp.UsuarioActual)
                {
                }
                else
                {
                    return new LinkedList<prestamo>();
                }
            }
            return datos.prestamos.prestamoUsuarioEstado(idUsuario, estado);
        }


        internal LinkedList<prestamo> prestamoUsuario(String idUsuario)
        {
            if (!idUsuarioValido(idUsuario))
            {
                throw new Exception("El id Usuario no puede ser nulo");
            }
            if (!cp.usuarioActualPuede(acciones.PRESTA_CONSULTA_TOD))
            {
                if (cp.usuarioActualPuede(acciones.PRESTA_CONSULTA_ACT) && idUsuario == cp.UsuarioActual)
                {
                    return prestamoTodosPendientesUsuario(cp.UsuarioActual);
                }
                else
                {
                    return new LinkedList<prestamo>();
                }
            }
            return datos.prestamos.prestamoPendienteUsuario(idUsuario);
        }

        internal LinkedList<prestamo> prestamoTodosPendientes()
        {
            if (!cp.usuarioActualPuede(acciones.PRESTA_CONSULTA_TOD))
            {
                if (cp.usuarioActualPuede(acciones.PRESTA_CONSULTA_ACT))
                {
                    return prestamoTodosPendientesUsuario(cp.UsuarioActual);
                }
            }
            return datos.prestamos.todosPrestamosPendientes();
        }

        internal LinkedList<prestamo> prestamoTodosPendientesUsuario(string idUsuario)
        {
            if (!cp.usuarioActualPuede(acciones.PRESTA_CONSULTA_TOD))
            {
                if (cp.usuarioActualPuede(acciones.PRESTA_CONSULTA_ACT) && cp.UsuarioActual == idUsuario)
                {
                    return datos.prestamos.prestamoPendienteUsuario(idUsuario);
                }
                else
                {
                    return new LinkedList<prestamo>();
                }
            }
            return datos.prestamos.prestamoPendienteUsuario(idUsuario);
        }

        internal LinkedList<prestamo> prestamoTodos()
        {
            if (!cp.usuarioActualPuede(acciones.PRESTA_CONSULTA_TOD))
            {
                cp.ExcepcionUsrSinPermisos();
            }
            return datos.prestamos.todosPrestamos();
        }

        internal LinkedList<prestamo> prestamoUsuarioActual()
        {
            if (!cp.usuarioActualPuede(acciones.PRESTA_CONSULTA_ACT))
            {
                cp.ExcepcionUsrSinPermisos();
            }
            return datos.prestamos.prestamoPendienteUsuario(cp.UsuarioActual);
        }

        internal LinkedList<prestamo> prestamosMorosos()
        {
            if (!cp.usuarioActualPuede(acciones.PRESTA_CONSULTA_TOD))
            {
                cp.ExcepcionUsrSinPermisos();
            }
            return datos.prestamos.prestamosMorosos();
        }

        internal LinkedList<prestamo> prestamosMorososUSRACT()
        {
            if (!cp.usuarioActualPuede(acciones.PRESTA_CONSULTA_TOD))
            {
                cp.ExcepcionUsrSinPermisos();
            }
            return datos.prestamos.prestamosMorosos(cp.usuarioActual().idUsuario);
        }

        internal LinkedList<prestamo> prestamosMorosos(String idUsuario)
        {
            if (!idUsuarioValido(idUsuario))
            {
                throw new Exception("El IdUsuario no puede ser nulo");
            }
            if (!cp.usuarioActualPuede(acciones.PRESTA_CONSULTA_TOD))
            {
                cp.ExcepcionUsrSinPermisos();
            }
            return datos.prestamos.prestamosMorosos(idUsuario);
        }

        internal LinkedList<prestamo> prestamosFecha(DateTime desde, DateTime hasta)
        {
            if (!Validacion.mayor(desde, hasta, true))
            {
                throw new Exception("El rango de fechas es incorrecto");
            }
            if (cp.usuarioActualPuede(acciones.PRESTA_CONSULTA_TOD))
            {
                cp.ExcepcionUsrSinPermisos();
            }
            return datos.prestamos.prestamoFecha(desde, hasta);
       }

        internal LinkedList<usuario> todosUsuarios()
        {
            if (!cp.usuarioActualPuede(acciones.PRESTA_CONSULTA_TOD))
            {
                if (cp.usuarioActualPuede(acciones.PRESTA_CONSULTA_ACT))
                {
                    usuario n = datos.usuarios.obtenerusuario(cp.usuarioActual().idUsuario);
                    LinkedList<usuario> g = new LinkedList<usuario>();
                    g.AddLast(n);
                    return g;
                }
                else
                {
                    return null;
                }
            }
            LinkedList<usuario> users = datos.usuarios.obtenerTodos();
            return users;
        }

        internal grupo obtenerGrupoUsuario(String idUsuario)
        {
            if (cp.usuarioActualPuede(acciones.USER_CONSULTAR_TOD))
            {
                String idGrupo = cp.ctrlUsuario.obtenerUsuario(idUsuario).idGrupo;
                return cp.datos.grupos.obtenergrupo(idGrupo);
            }
            else 
            {
                return null;
            }
        }

        #endregion

        #region "atributos"

        datosAplicacion datos;
        controlPrincipal cp;

        #endregion


        internal static prestamo buscarPrestamos(LinkedList<prestamo> prestamosActuales, string cod)
        {
            if (prestamosActuales != null && !string.IsNullOrEmpty(cod))
            {
                foreach (prestamo act in prestamosActuales)
                {
                    if (act.codPrestamo == cod)
                    {
                        return act;
                    }
                }
            }
            return null;
        }
    }
}
